package com.org.csu.service.Impl;

import com.org.csu.converter.FlowConverter;
import com.org.csu.dao.KeywordRepository;
import com.org.csu.dto.KeywordDTO;
import com.org.csu.entity.CompKey;
import com.org.csu.entity.Keyword;
import com.org.csu.entity.Word;
import com.org.csu.service.KeywordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.org.csu.converter.KeywordConverter.convertKeyword;
import static com.org.csu.converter.KeywordConverter.convertKeywordList;

/**
 * @author YigongLily
 * @version V1.0
 * Copyright (c) 2024, t8669@qq.com All Rights Reserved.
 * @ProjectName:e-commerce-back
 * @Title: KeywordServiceImpl
 * @Package com.org.csu.service.Impl
 * @Description: ksimpl
 * @date 2024/12/15 11:56
 */
@Service
public class KeywordServiceImpl implements KeywordService {
    @Autowired
    private KeywordRepository keywordRepository;
    @Override
    public KeywordDTO getKeywordInfo(String keyword) {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        String formattedDate = currentDate.format(formatter);
        System.out.println("check"+keyword+formattedDate);
        List<KeywordDTO> keywordDTOList = convertKeywordList(keywordRepository.findByWordAndDate(keyword, formattedDate));
        for (KeywordDTO dto : keywordDTOList) {
            System.out.println("Word: " + dto.getWord() + ", Date: " + dto.getDate() + ", Hot: " + dto.getHot());
        }
        if (keywordDTOList.isEmpty()) {
            return null;
        }
        return keywordDTOList.get(0);
    }

    @Override
    public List<KeywordDTO> getLongTailWords(String keyword) {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        String formattedDate = currentDate.format(formatter);
        List<Keyword> longTailKeywords = keywordRepository.findAllByWordAndDate(keyword, formattedDate);
        if (longTailKeywords.size() > 10) {
            longTailKeywords = longTailKeywords.stream()
                    .sorted((k1, k2) -> k2.getHot().compareTo(k1.getHot())) // 根据hot降序排序
                    .limit(10) // 取前10个
                    .collect(Collectors.toList());
        }

        return convertKeywordList(longTailKeywords);
    }

    @Override
    public List<CompKey> getCompetitiveWords(String keyword) {
        List<Keyword> allKeywords = keywordRepository.findAll();
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        String formattedDate = currentDate.format(formatter);
        List<Keyword> targetKeywordList = keywordRepository.findByWordAndDate(keyword, formattedDate);

        if (targetKeywordList == null || targetKeywordList.isEmpty()) {
            return null;
        }else{
            Keyword targetKeyword = targetKeywordList.get(0);


            List<CompKey> competitors = new ArrayList<>();
            allKeywords.forEach(k -> {
                if (!k.getWord().equals(keyword)) {
                    BigDecimal comp = calculateCompetitiveness(targetKeyword, k,0.1,0.2);
                    competitors.add(new CompKey(k.getWord(), k.getHot(), comp));
                }
            });

            // Sort by competitiveness in descending order
            competitors.sort((k1, k2) -> k2.getComp().compareTo(k1.getComp()));

            return competitors.stream().limit(10).collect(Collectors.toList());
        }
    }
    private BigDecimal calculateCompetitiveness(Keyword target, Keyword competitor, double w1, double w2) {
        int hotDifference = Math.abs(target.getHot() - competitor.getHot());
        BigDecimal valueRatio = BigDecimal.ZERO;

        // 避免除以0，如果competitor.getValue()为0，则valueRatio设置为1
        if (competitor.getValue().compareTo(BigDecimal.ZERO) != 0) {
            valueRatio = target.getValue()
                    .divide(competitor.getValue(), 4, BigDecimal.ROUND_HALF_UP);
        } else {
            valueRatio = BigDecimal.ONE; // 如果competitor.getValue()为0，valueRatio设置为1
        }

        FlowConverter flowConverter = new FlowConverter();
        double targetFlow = flowConverter.parseFlow(String.valueOf(target.getFlow()));
        double competitorFlow = flowConverter.parseFlow(String.valueOf(competitor.getFlow()));

        // 确保流量不为零
        if (targetFlow == 0) {
            targetFlow = 1; // 如果目标流量为0，设置为1以避免除以零
        }
        if (competitorFlow == 0) {
            competitorFlow = 1; // 如果竞争流量为0，设置为1以避免除以零
        }

        BigDecimal maxHot = BigDecimal.valueOf(Math.max(target.getHot(), competitor.getHot()));
        if (maxHot.compareTo(BigDecimal.ZERO) == 0) {
            maxHot = BigDecimal.ONE; // 如果最大热度为0，设置为1以避免除以零
        }

        BigDecimal flowRatio = BigDecimal.valueOf(targetFlow)
                .divide(BigDecimal.valueOf(competitorFlow), 4, BigDecimal.ROUND_HALF_UP);

        BigDecimal competitiveness = BigDecimal.valueOf(hotDifference)
                .add(BigDecimal.valueOf(w1).multiply(valueRatio))
                .add(BigDecimal.valueOf(w2).multiply(flowRatio))
                .divide(maxHot, 2, BigDecimal.ROUND_HALF_UP);

        return competitiveness;
    }
//    private BigDecimal calculateCompetitiveness(Keyword target, Keyword competitor) {
//        // 计算热度差值
//        int hotDifference = Math.abs(target.getHot() - competitor.getHot());
//
//        // 计算价值比，避免除以0，并确保valueRatio在0到1之间
//        BigDecimal targetValue = target.getValue();
//        BigDecimal competitorValue = competitor.getValue();
//        BigDecimal valueRatio;
//        if (targetValue.compareTo(BigDecimal.ZERO) == 0 ) {
//            // 如果目标或竞争关键词的价值为0，则无法计算价值比，可以设置一个默认值或抛出异常
//            valueRatio = BigDecimal.valueOf(0.01);
//        }
//        if(competitorValue.compareTo(BigDecimal.ZERO) == 0){
//            competitorValue = BigDecimal.valueOf(0.01);
//        }
//
//        valueRatio = targetValue.divide(competitorValue, 2, RoundingMode.HALF_UP);
//
//
//        // 假设最大差异是目标关键词热度的值
//        BigDecimal maxDifference = BigDecimal.valueOf(target.getHot());
//
//        // 计算竞争力度，热度差异与价值比的乘积，再除以最大差异
//        BigDecimal competitiveness = BigDecimal.valueOf(hotDifference)
//                .divide(maxDifference, 2, BigDecimal.ROUND_HALF_UP)
//                .multiply(valueRatio);
//
//        return competitiveness;
//    }


    @Override
    public Integer getKeywordRate(String keyword) {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        String formattedDate = currentDate.format(formatter);
        Keyword keywordInfo = keywordRepository.findByWordAndDate(keyword, formattedDate).get(0);
        if (keywordInfo == null) {
            return null;
        }
        return keywordInfo.getRate();
    }


    @Override
    public List<Word> getKeywordTrend(String keyword) {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        String formattedEndDate = currentDate.format(formatter);
        LocalDate startDate = currentDate.minusDays(6);
        String formattedStartDate = startDate.format(formatter);

        // 创建一个包含近七天日期的列表
        List<String> dateList = new ArrayList<>();
        LocalDate tempDate = startDate;
        while (!tempDate.isAfter(currentDate)) {
            dateList.add(tempDate.format(formatter));
            tempDate = tempDate.plusDays(1);
        }

        List<Keyword> keywords = keywordRepository.findHotTrendWithDate(keyword, dateList);
        if (keywords == null) {
            return null;
        }

        // 准备一个Map来存储日期和hot值，键为日期字符串
        Map<String, Integer> hotMap = new HashMap<>();
        for (Keyword k : keywords) {
            hotMap.put(k.getDate(), k.getHot());
        }


        // 转换结果为Word对象列表
        List<Word> wordList = new ArrayList<>();
        for (String date : dateList) {
            Integer hot = hotMap.getOrDefault(date, 0);
            wordList.add(new Word(date, hot));
        }

        return wordList;
    }
}